import _ from 'lodash';
export * from "./types/index";
export * from "./compInst";
import { ICmpnt, clone, setConf, IWidget, IContainer, IPage } from "./types/index";
import { CompInst, VueComponent, ICompInst } from "./compInst";
import { App } from 'vue';



// 组件管理器类  
export class CompLoader {
  installed: Boolean = false;
  compInst: ICompInst = new CompInst(null)
  containers: { [key: string]: IContainer } = {};
  bars: { [key: string]: IWidget } = {};
  widgets: { [key: string]: IWidget } = {};
  pages: { [key: string]: IPage } = {};
  presets: { [key: string]: IWidget } = {};
  all: { [key: string]: any } = {};

  constructor(modules: { [key: string]: any }) {
    this.addModules(modules);
  }
  public addModules(modules: { [key: string]: any }) {
    for (const fullPath in modules) {
      const lastName = _.last(fullPath.split('/'));
      if (lastName?.startsWith('_')){
        console.log('ignore', fullPath);
        continue;
      }
       
      const module = modules[fullPath];
      this.addModule(module);
    }
  }
  public addModule(module: any) {
    const moduleDefault = module.default || module;
    for (const name in moduleDefault) {
      const cmpnt = moduleDefault[name];
      const category = cmpnt.category;
      if (!category) {
        continue;
      }

      const cmpntName = _.upperFirst(_.camelCase(cmpnt.ctl.name));
      const cmpntModule: any = clone(cmpnt);
      switch (category) {
        case 'widgets':
          this.widgets[cmpntName] = cmpntModule as IWidget;
          break
        case 'containers':
          this.containers[cmpntName] = cmpntModule as IContainer;
          break;
        case 'pages':
          this.pages[cmpntName] = cmpntModule as IPage;
          break
        case 'bars':
          this.bars[cmpntName] = cmpntModule as IWidget;
          break;
        case 'presets':
          this.presets[cmpntName] = cmpntModule as IWidget;
          break
        default:
          throw new Error(`组件类别'${category}'不存在`);
      }
      this.all[cmpntName] = cmpntModule;
    }
  }
  public install(app: App) {
    if (this.installed) return
    this.installed = true
    const modules = import.meta.glob<{ default: VueComponent }>(["./**/*.vue"], { eager: true })
    this.addComponents(modules)
    this.compInst.install(app)
  }
  public addComponents(modules: Record<string, { default: VueComponent }>) {
    this.compInst.addComponents(modules)
  }


  // 查找组件  
  public find(name: string): ICmpnt {
    const formattedName = _.upperFirst(_.camelCase(name));
    const result = this.all[formattedName];
    if (!result)
      throw new Error(`未找到组件'${formattedName}'`);
    return result;
  }
  public group(name: string): ICmpnt[] {
    const formattedName = _.upperFirst(_.camelCase(name));

    let result: ICmpnt[] = [];
    _.each(this.all, (value) => {
      if (_.upperFirst(_.camelCase(value.ctl.group)) === formattedName) {
        result.push(value)
      }
    });
    return result;
  }


  public resetBind(cmpnt: ICmpnt) {
    let that = this
    setConf(cmpnt, function (name: string): ICmpnt {
      return that.find(name)
    })
  }


  public getAll(): any[] {
    return Object.values(this.all);
  }
}

// 导入组件模块
const modules = import.meta.glob(["./**/*.ts"], { eager: true });
const compLoader = new CompLoader(modules);


export default compLoader;